package com.fengsh.nacos.components;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;


/**
 * @标题 局部过滤器
 * @作者 fengsh998
 * @创建时间 2024/2/1
 * @功能描述
 */
//类名必须以GatewayFilterFactory结尾
@Component
public class PartsCustomGatewayFilterFactory extends AbstractGatewayFilterFactory<PartsCustomGatewayFilterFactory.Config> implements Ordered {

    private static final Logger logger = LoggerFactory.getLogger(PartsCustomGatewayFilterFactory.class);
    /**
     * 局部过滤规则的使用，例如：类名为ABCGatewayFilterFactory,则yml中的过滤器里的name属性则为ABC
     * 如：
     *   ...
     *   filters:
     *     - StripPrefix=1
     *     - name: ABC
     *       args:
     *         str_value1: xxx  #这个值会通过ABCGatewayFilterFactory.config里定义setter,getter传值。
     *         int_value2: 45
     *         bool_value3: false
     *
     */

    public PartsCustomGatewayFilterFactory() {
        super(Config.class);
    }

    @Override
    public GatewayFilter apply(Config config) {
        return new GatewayFilter() {
            @Override
            public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
                logger.info("【局部过滤器】前置过滤实现处.....");
                logger.info("【局部过滤器】配置值内容：" + config.str_value1);
                logger.info("【局部过滤器】配置值内容：" + config.int_value2);
                logger.info("【局部过滤器】配置值内容：" + config.bool_value3);
                return chain.filter(exchange).then(Mono.fromRunnable(
                        () -> {
                            logger.info("【局部过滤器】后置过滤实现处.....");
                        }
                ));
            }
        };
    }

    @Override
    public int getOrder() {
        return 1;
    }

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public static class Config {
        private String str_value1;
        private Integer int_value2;
        private Boolean bool_value3;
    }
}
